﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Configuration;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Text;
using System.Windows.Media.Imaging;
using System.Xml.Linq;

namespace YAWD.Utils
{
    class Util
    {
        public static BitmapSource CreateSmallImage(byte[] imageData)
        {
            try
            {
                if (imageData == null || imageData.Length == 0)
                    return null;

                BitmapImage result = new BitmapImage();
                MemoryStream mem = new MemoryStream(imageData);
                result.BeginInit();
                result.StreamSource = mem;
                result.DecodePixelWidth = 100;
                result.CacheOption = BitmapCacheOption.OnLoad;
                result.CreateOptions = BitmapCreateOptions.IgnoreColorProfile;
                result.EndInit();
                result.Freeze();
                mem.Dispose();

                return result;
            }
            catch (NotSupportedException ex)
            {
                LogException(ex);
                return null;
            }
            catch (ArgumentException ex)
            {
                LogException(ex);
                return null;
            }
            catch (InvalidOperationException ex2)
            {
                LogException(ex2);
                return null;
            }
        }

        public static byte[] getLocalImage(string strFilePath, string strFileName, bool isFile)
        {
            DirectoryInfo objFolder;

            if (isFile == false && string.IsNullOrEmpty(strFileName) == false)
            {
                if (Directory.Exists(Path.Combine(strFilePath.Trim(), strFileName.Trim())) == false)
                    return null;

                objFolder = new DirectoryInfo(Path.Combine(strFilePath.Trim(), strFileName.Trim()));
            }
            else
            {
                if (Directory.Exists(strFilePath.Trim()) == false)
                    return null;

                objFolder = new DirectoryInfo(strFilePath.Trim());
            }

            FileInfo[] lstImages = objFolder.GetFiles("*.jpg", SearchOption.AllDirectories);

            if (lstImages.Count() > 0)
            {
                if (lstImages.Count() == 1)
                {
                    return Util.LoadImageData(lstImages[0].FullName);
                }
                else
                {
                    string strImagePath = string.Empty;
                    long lngSize = 0;

                    foreach (FileInfo item in lstImages)
                    {
                        if (item.Length > lngSize)
                        {
                            strImagePath = item.FullName;
                            lngSize = item.Length;
                        }
                    }

                    return Util.LoadImageData(strImagePath);
                }
            }
            return null;
        }
        public static string GetHtmlPage(string strUrl, Encoding objEncoding, BrowserType browserType)
        {
            try
            {
                string strResults = string.Empty;

                if (string.IsNullOrEmpty(strUrl) == false)
                {

                    strUrl = strUrl.Replace(" ", "%20");
                    WebClient objService = new WebClient();
                    objService.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip,deflate");
                    switch (browserType)
                    {
                        case BrowserType.Firefox4:
                            objService.Headers.Add(HttpRequestHeader.UserAgent, "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:2.0.1) Gecko/20100101 Firefox/4.0.1");
                            break;
                        case BrowserType.None:
                        default:
                            break;
                    }


                    if (objEncoding != null)
                        objService.Encoding = objEncoding;

                    using (MemoryStream memoryStream = new MemoryStream(objService.DownloadData(strUrl)))
                    {

                        switch (objService.ResponseHeaders[HttpResponseHeader.ContentEncoding])
                        {
                            case "gzip":
                                strResults = new StreamReader(new GZipStream(memoryStream, CompressionMode.Decompress), objEncoding).ReadToEnd();
                                break;
                            case "deflate":
                                strResults = new StreamReader(new DeflateStream(memoryStream, CompressionMode.Decompress), objEncoding).ReadToEnd();
                                break;
                            default:
                                strResults = new StreamReader(memoryStream, objEncoding).ReadToEnd();
                                break;
                        }
                    }


                    //Replace HTML entity references so that we can load into XElement
                    strResults = strResults.Replace("&nbsp;", "");
                    strResults = strResults.Replace("&", "&amp;");
                }

                return strResults;

            }
            catch (Exception ex)
            {
                LogException(ex);
                return null;
            }
        }
        public static string GetHtmlPage(string strUrl, Encoding objEncoding)
        {
            return GetHtmlPage(strUrl, objEncoding, BrowserType.None);
        }
        public static string GetHtmlPage(string strUrl, NameValueCollection objValues)
        {
            string strResults = string.Empty;

            if (string.IsNullOrEmpty(strUrl) == false)
            {

                strUrl = strUrl.Replace(" ", "%20");
                WebClient objService = new WebClient();
                byte[] objResults = objService.UploadValues(strUrl, objValues);

                strResults = Encoding.ASCII.GetString(objResults);
            }

            return strResults;
        }
        public static byte[] getImage(string strUrl)
        {
            return getImage(strUrl, string.Empty, BrowserType.None);
        }
        public static byte[] getImage(string strUrl, string referer)
        {
            return getImage(strUrl, referer, BrowserType.None);
        }
        public static byte[] getImage(string strUrl, string referer, BrowserType browserType)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(strUrl)) return null;

                byte[] objResults = null;
                strUrl = strUrl.Replace(" ", "%20");
                if (strUrl.EndsWith(".js", true, CultureInfo.InvariantCulture) == false)
                {
                    WebClient objService = new WebClient();

                    switch (browserType)
                    {
                        case BrowserType.Firefox4:
                            objService.Headers.Add(HttpRequestHeader.UserAgent, "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:2.0.1) Gecko/20100101 Firefox/4.0.1");
                            break;
                        case BrowserType.None:
                        default:
                            break;
                    }

                    if (string.IsNullOrWhiteSpace(referer) == false)
                        objService.Headers.Add("Referer", referer);

                    objResults = objService.DownloadData(strUrl.Trim());
                }

                return objResults;

            }
            catch (Exception ex)
            {
                Util.LogException(ex);
                return null;
            }
        }
        public static XElement getRest(Uri strUrl)
        {
            try
            {
                HttpWebRequest request = System.Net.WebRequest.Create(strUrl) as HttpWebRequest;
                if (request != null)
                {
                    request.UserAgent = "myCollections";
                    request.KeepAlive = false;
                    request.Timeout = 35 * 1000;

                    // Get response  
                    HttpWebResponse response = request.GetResponse() as HttpWebResponse;

                    if (response != null)
                    {
                        // Get the response stream  
                        StreamReader reader = new StreamReader(response.GetResponseStream());

                        // Read it into a StringBuilder  
                        StringBuilder sbSource = new StringBuilder(reader.ReadToEnd());
                        if (sbSource.Length > 0)
                            return XElement.Parse(sbSource.ToString());
                        else
                            return null;

                    }
                }
                return null;
            }
            catch (Exception ex)
            {
                LogException(ex);
                return null;
            }
        }

        public static byte[] LoadImageData(string filePath)
        {
            if (string.IsNullOrWhiteSpace(filePath)) return null;

            FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read);
            BinaryReader br = new BinaryReader(fs);

            byte[] imageBytes = br.ReadBytes((int)fs.Length);
            br.Close();

            fs.Close();
            return imageBytes;
        }
        public static void LogException(Exception ex)
        {
            StreamWriter objTemp;
            string strName = "Errors" + DateTime.Now.Year + DateTime.Now.Month + DateTime.Now.Day + ".log";
            if (File.Exists(strName) == false)
            {
                objTemp = File.CreateText(strName);
                objTemp.Close();
            }

            using (
                StreamWriter sw =
                    File.AppendText("Errors" + DateTime.Now.Year + DateTime.Now.Month + DateTime.Now.Day + ".log"))
            {
                sw.WriteLine("Message :" + ex.Message);
                sw.WriteLine("Source :" + ex.Source);
                if (ex.TargetSite != null) sw.WriteLine("TargetSite :" + ex.TargetSite);
                if (ex.InnerException != null)
                    sw.WriteLine("InnerException :" + ex.InnerException);

                sw.WriteLine("StackTrace :" + ex.StackTrace);
                sw.WriteLine("------------------------------------------------------------");
                sw.Flush();
                sw.Close();
            }
        }

        public static void SaveToConfigFile(string strKey, string strValue)
        {
            Configuration objConfig = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            AppSettingsSection objAppsettings = (AppSettingsSection)objConfig.GetSection("appSettings");

            try
            {

                if (objAppsettings != null)
                {
                    objAppsettings.Settings[strKey].Value = strValue;
                }
            }
            catch (Exception ex)
            {
                Util.LogException(ex);
            }
            finally
            {
                objConfig.Save();
                ConfigurationManager.RefreshSection("appSettings");
            }
        }

        public static string GetElementValue(XElement node, string elementName)
        {
            var query = from element in node.Elements()
                        where element.Name == elementName
                        select element.Value;

            List<string> elementeValueList = new List<string>(query);
            return (elementeValueList.Count > 0)
                       ? elementeValueList[0]
                       : string.Empty;
        }
        public static string GetElementValue(XElement node, string elementName,
                                             string attributName, string attributValue)
        {
            var query = from element in node.Elements()
                        where element.Name == elementName &&
                              element.Attribute(attributName).Value == attributValue
                        select element.Value;

            if (query != null)
            {
                List<string> elementeValueList = new List<string>(query);
                return (elementeValueList.Count > 0)
                           ? elementeValueList[0]
                           : string.Empty;
            }
            else return string.Empty;
        }
        public static string GetAttributValue(XElement node, string attributeName)
        {
            var query = from element in node.Attributes()
                        where element.Name == attributeName
                        select element.Value;

            List<string> elementeValueList = new List<string>(query);
            return (elementeValueList.Count > 0)
                       ? elementeValueList[0]
                       : string.Empty;
        }
        public static string GetAttributValue(XElement node, string elementName,
                                          string attributName)
        {
            var query = from element in node.Elements()
                        where element.Name == elementName
                        select element;

            if (query != null)
            {
                List<XElement> elementeValueList = query.ToList<XElement>();
                if (elementeValueList.Count > 0)
                    return GetAttributValue(elementeValueList[0], attributName);
                else
                    return string.Empty;
            }
            else return string.Empty;
        }
        public static Version getAppVersion()
        {
            Assembly assembly = Assembly.GetExecutingAssembly();
            Version currentVersion = assembly.GetName().Version;
            return currentVersion;
        }

    }
}
